package org.jeecg.modules.common.consumer;

import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.common.bean.RabbitMqConstant;
import org.jeecg.modules.common.rabbitmq.RabbitmqUtil;
import org.jeecg.modules.practice.entity.Practice;
import org.jeecg.modules.practice.service.IPracticeService;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.Header;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * @author 13240
 */
@Slf4j
@Configuration
public class RabbitMqConsumer {

    @Resource
    private IPracticeService practiceService;

    /**
     * 1. 服务端初始化方式去创建交换机
     */
    RabbitMqConsumer() {
        System.out.println("初始化对应的mq");
        RabbitmqUtil rabbitmqUtil = new RabbitmqUtil();
        rabbitmqUtil.archivesBinding(RabbitMqConstant.CONVENIENT_EXCHANGE, RabbitMqConstant.CONVENIENT_QUEUE, RabbitMqConstant.CONVENIENT_KEY);

        rabbitmqUtil.archivesBinding(RabbitMqConstant.TRANS_EXCHANGE, RabbitMqConstant.TRANS_QUEUE, RabbitMqConstant.TRANS_KEY);

//        rabbitmqUtil.archivesBinding(RabbitMqConstant.TRANS_EXCHANGE, RabbitMqConstant.TRANS_QUEUE_TB, RabbitMqConstant.TRANS_KEY);

    }

    /**
     * 2. 服务端监控CONVENIENT_QUEUE队列
     * @param jsonStr 消息内容
     * @param deliveryTag 消费消息的index
     * @param channel mq信道连接
     */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue(RabbitMqConstant.CONVENIENT_QUEUE))
    public void consumer(String jsonStr, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) throws IOException {

        try {
            // 3. 处理消息
            Practice practice = JSONObject.parseObject(jsonStr, Practice.class);
            practiceService.saveOrUpdate(practice);
            log.info("jsonStr: {}", jsonStr);

            // 4. 在处理完消息后手动进行确认
            /*
             * 参数1： 消费消息的index
             * 参数2： 是否批量进行确认
             * */
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue(RabbitMqConstant.TRANS_QUEUE), priority = "3")
    public void transConsumer(String jsonStr, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) throws IOException {
        try {
            // 3. 处理消息
            Practice practice = JSONObject.parseObject(jsonStr, Practice.class);
            practiceService.saveOrUpdate(practice);
            log.info("transConsumer-jsonStr: {}", jsonStr);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 4. 在处理完消息后手动进行确认
            /*
             * 参数1： 消费消息的index
             * 参数2： 是否批量进行确认
             */
            // 对异常消息的处理，true表示重排序，false表示丢弃
            channel.basicAck(deliveryTag, false);
        }
    }

    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue(RabbitMqConstant.TRANS_QUEUE_TB), priority = "2")
    public void transConsumerTb(String jsonStr, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) throws IOException {
        try {
            // 3. 处理消息
            Practice practice = JSONObject.parseObject(jsonStr, Practice.class);
            practiceService.saveOrUpdate(practice);
            log.info("transConsumerTb-jsonStr: {}", jsonStr);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 4. 在处理完消息后手动进行确认
            /*
             * 参数1： 消费消息的index
             * 参数2： 是否批量进行确认
             * */
            channel.basicAck(deliveryTag, false);
        }
    }

    // todo 消息保存、死信、自动创建
}
